﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace Saxxon.LibDoomSharp.Lumps
{
    public class LinedefsEntry : SerializableBase
    {
        /// <summary>
        /// Length of a Linedef table entry in bytes.
        /// </summary>
        public const int ENTRY_LENGTH = 14;

        /// <summary>
        /// Starting Vertex.
        /// </summary>
        public Int16 VertexStart;

        /// <summary>
        /// Ending vertex.
        /// </summary>
        public Int16 VertexEnd;

        /// <summary>
        /// Flags that determine behavior.
        /// </summary>
        public LinedefsEntryFlags Flags;

        /// <summary>
        /// Type that determines behavior.
        /// </summary>
        public Int16 Type;

        /// <summary>
        /// Sector tag to tie behavior to.
        /// </summary>
        public Int16 Tag;

        /// <summary>
        /// Sidedef index for the right side of the linedef.
        /// </summary>
        public Int16 RightSidedef;

        /// <summary>
        /// Sidedef index for the left side of the linedef.
        /// </summary>
        public Int16 LeftSidedef;

        /// <summary>
        /// Read Linedef data.
        /// </summary>
        protected override void Read(Stream stream, int length)
        {
            DataReader reader = new DataReader(stream);
            VertexStart = reader.ReadInt16();
            VertexEnd = reader.ReadInt16();
            Flags = (LinedefsEntryFlags)reader.ReadInt16();
            Type = reader.ReadInt16();
            Tag = reader.ReadInt16();
            RightSidedef = reader.ReadInt16();
            LeftSidedef = reader.ReadInt16();
        }

        /// <summary>
        /// Retrieve string representation of Linedef.
        /// </summary>
        public override string ToString()
        {
            return "Linedef { Vertex=" +
                VertexStart.ToString() + ", " + VertexEnd.ToString() +
                "; Flags=" + Flags.ToString() +
                "; Type=" + Type.ToString() +
                "; Tag=" + Tag.ToString() +
                "; RightSide=" + RightSidedef.ToString() +
                "; LeftSide=" + LeftSidedef.ToString() +
                "; }";
        }

        /// <summary>
        /// Write linedef data.
        /// </summary>
        protected override void Write(Stream stream)
        {
            DataWriter writer = new DataWriter(stream);
            writer.WriteInt16(VertexStart);
            writer.WriteInt16(VertexEnd);
            writer.WriteInt16((short)Flags);
            writer.WriteInt16(Type);
            writer.WriteInt16(Tag);
            writer.WriteInt16(RightSidedef);
            writer.WriteInt16(LeftSidedef);
        }
    }

    /// <summary>
    /// Flags for use with LinedefsEntry.
    /// </summary>
    [FlagsAttribute]
    public enum LinedefsEntryFlags : short
    {
        /// <summary>
        /// No actors can pass this linedef.
        /// </summary>
        Impassible = 0x0001,

        /// <summary>
        /// Monsters cannot pass this linedef.
        /// </summary>
        BlockMonsters = 0x0002,

        /// <summary>
        /// This linedef contains both a right and left sidedef.
        /// </summary>
        TwoSided = 0x0004,

        /// <summary>
        /// Upper sidedef origin is unpegged.
        /// </summary>
        UpperUnpegged = 0x0008,

        /// <summary>
        /// Middle and lower sidedef origin is unpegged.
        /// </summary>
        LowerUnpegged = 0x0010,

        /// <summary>
        /// Show as a solid wall on the minimap.
        /// </summary>
        Secret = 0x0020,

        /// <summary>
        /// This linedef blocks sound.
        /// </summary>
        BlockSound = 0x0040,

        /// <summary>
        /// This linedef is never shown on the minimap. 
        /// </summary>
        Hide = 0x0080,

        /// <summary>
        /// This linedef is always shown on the minimap.
        /// </summary>
        Show = 0x0100
    }
}
